package com.app.view_controller;

import java.net.URI;
import java.util.ArrayList;

import com.app.alarm.R;
import com.app.model.AlarmDataManager;
import com.app.model.AlarmDataManager.AlarmLoader;
import com.app.util.ApplicationMediator;
import com.app.view_controller.custom_view.nhaarman.listviewanimations.ArrayAdapter;
import com.app.view_controller.custom_view.nhaarman.listviewanimations.swinginadapters.prepared.SwingBottomInAnimationAdapter;
import com.app.view_controller.custom_view.nhaarman.listviewanimations.swinginadapters.prepared.SwingLeftInAnimationAdapter;

import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.app.LoaderManager;
import android.content.Context;
import android.content.CursorLoader;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.database.Cursor;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.media.ToneGenerator;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.RelativeLayout;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;

@SuppressWarnings("unused")
public class AlarmtoneDialogFragment extends DialogFragment {
	/**
	 * Constant used as a key by the Observer to pass the new tone uri to the
	 * AlarmSetterDialog.
	 */
	private static final String TAG = "ALARMTONE_DIALOG_FRAGMENT";
	private static final boolean DEBUG = true;
	private AlarmDataManager mAlarmData;
	private java.util.ArrayList<TrackInfo> mTrackList;
	private Ringtone tone;

	public AlarmtoneDialogFragment() {

	}

	@SuppressLint("InflateParams")
	@Override
	public Dialog onCreateDialog(Bundle savedInstanceState) {
		// Use the Builder class for convenient dialog construction
		Dialog dialog = super.onCreateDialog(savedInstanceState);
		dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
		// Get an alarm data from the tag set in the AlarmSetterDialog.
		mAlarmData = AlarmLoader.convertFromJSON(getTag(), getActivity());
		View container = (View) LayoutInflater.from(getActivity()).inflate(R.layout.tone_dialog, null);
		ListView mListView = (ListView) container.findViewById(R.id.tone_list_view);
		ToneListAdapter mAdapter = new ToneListAdapter(createAdapterArray());
		final SwingLeftInAnimationAdapter mSwing = new SwingLeftInAnimationAdapter(mAdapter);
		// Connect ListView with Adapter.
		mListView.setAdapter(mSwing);
		mSwing.setAbsListView(mListView);
		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

		builder.setTitle("list").setPositiveButton("ok", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				if (tone != null)
					tone.stop();
				int i = 0;
				while (i < mTrackList.size()) {
					if (mTrackList.get(i).selected) {
						ApplicationMediator mObserver = ApplicationMediator.getInstance();
						mObserver.sendMessageWithAttachedData(AlarmSetterDialog.URI_FROM_TONE_DIALOG, mTrackList.get(i).uri.toString());
					}
					i++;
				}
			}

		}).setNegativeButton("cancel", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				// User cancelled the dialog
				if (tone != null)
					tone.stop();
			}
		}).setView(container);
		// Create the AlertDialog object and return it
		return builder.create();
	}

	@SuppressWarnings("deprecation")
	private ArrayList<TrackInfo> createAdapterArray() {

		RingtoneManager mRingtoneManager = new RingtoneManager(getActivity());
		mRingtoneManager.setType(RingtoneManager.TYPE_ALL);
		// Get a cursor that allows to scan the database that contains all the
		// ringtones.
		Cursor mCursor = mRingtoneManager.getCursor();
		// Let the activity manage the lifecycle of the cursor.
		getActivity().startManagingCursor(mCursor);
		mCursor.moveToFirst();
		ArrayList<TrackInfo> trackList = new ArrayList<AlarmtoneDialogFragment.TrackInfo>();
		// Scan the database and put the information into an ArrayList.
		// To get the complete uri for a track i must link together the uri from
		// the URI_COMUMN with the id from the ID_COLUMN.
		while (!mCursor.isAfterLast()) {
			trackList.add(new TrackInfo(mCursor.getString(RingtoneManager.TITLE_COLUMN_INDEX), Uri.parse(mCursor
					.getString(RingtoneManager.URI_COLUMN_INDEX) + "/" + mCursor.getString(RingtoneManager.ID_COLUMN_INDEX)), false));
			mCursor.moveToNext();
		}
		String defaultToneUri = mAlarmData.getAlarmToneUri().toString();
		int i = 0;
		while (i < trackList.size() && !defaultToneUri.equals(trackList.get(i).uri.toString())) {
			i++;
		}
		if (DEBUG)
			Log.d(TAG, "tracklist   " + trackList.get(i).uri);
		trackList.get(i).selected = true;

		return trackList;
	}

	/**
	 * Static class that incapsulate all the information needed for a specific
	 * track. It has 3 variables that must be accessed directly. title is the
	 * title of the track; uri is the path of the track and selected specifies
	 * what is the current selected track.
	 * 
	 * @author Nick
	 * 
	 */
	private static class TrackInfo {
		String title;
		Uri uri;
		boolean selected;

		/**
		 * 
		 * @param title
		 *            title of the track
		 * @param uri
		 *            path of the track
		 * @param selected
		 *            boolean that indicates if this is the actual ringtone for
		 *            the alarm.
		 */
		public TrackInfo(String title, Uri uri, boolean selected) {
			this.title = title;
			this.uri = uri;
			this.selected = selected;
		}
	}

	private class ToneListAdapter extends ArrayAdapter<TrackInfo> implements OnCheckedChangeListener, android.view.View.OnClickListener {
		/**
		 * A reference of this adapter used in onCheckedChanged.
		 */
		private ToneListAdapter thisAdapter;

		public ToneListAdapter(java.util.ArrayList<TrackInfo> arrayList) {
			super(arrayList);
			mTrackList = arrayList;
			thisAdapter = this;
		}

		@SuppressLint("InflateParams")
		@Override
		public View getView(int position, View cell, ViewGroup parent) {
			if (cell == null) {
				cell = getActivity().getLayoutInflater().inflate(R.layout.tone_dialog_cell, null);
				ViewHolder holder = new ViewHolder((RadioButton) cell.findViewById(R.id.tone_cell_radio_button));
				cell.setTag(holder);
			}
			ViewHolder holder = (ViewHolder) cell.getTag();
			holder.position = position;
			holder.button.setText(mTrackList.get(position).title);
			holder.button.setChecked(mTrackList.get(position).selected);
			holder.button.setOnCheckedChangeListener(this);
			holder.button.setOnClickListener(this);
			holder.button.setTag(holder);
			return cell;
		}

		@Override
		public void onCheckedChanged(CompoundButton view, boolean value) {
			if (value) {
				ViewHolder holder = (ViewHolder) view.getTag();
				// Set all the buttons to not checked
				int i = 0;
				for (i = 0; i < mTrackList.size(); i++)
					mTrackList.get(i).selected = false;
				// Set the clicked button to checked
				mTrackList.get(holder.position).selected = true;
				// Notify the adapter the changes in order to get getView
				// called.
				thisAdapter.notifyDataSetChanged();

			}
		}

		@Override
		public void onClick(View v) {
			// When a button is clicked its track must start.
			ViewHolder holder = (ViewHolder) v.getTag();
			// If there is a tone playing stop it.
			if (tone != null)
				tone.stop();
			tone = RingtoneManager.getRingtone(getActivity(), mTrackList.get(holder.position).uri);
			tone.play();

		}

	}

	/**
	 * Static class that encapsulates the informations needed for each track. It
	 * contains 2 variables that must be accessed directly. The RadioButton is
	 * the view of the cell and the position its position.
	 * 
	 * @author Nick
	 * 
	 */
	private static class ViewHolder {

		RadioButton button;
		int position;

		/**
		 * Constructor that allows to set a value to the RadioButton View.
		 * 
		 * @param b
		 *            The RadioButton.
		 */
		public ViewHolder(RadioButton b) {
			button = b;
		}

	}
}
